package com.okex.demo.model;

import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 产品行情信息实体类
 * 表示OKX交易所中的一个产品行情信息，包含最新价格、买卖盘报价、24小时成交数据等
 */
@Data
public class TickerInfo {
    private String instType;    // 产品类型，如 SPOT（币币）、SWAP（永续合约）
    private String instId;      // 产品ID，如 BTC-USDT
    private BigDecimal last;    // 最新成交价
    private BigDecimal lastSz;  // 最新成交的数量
    private BigDecimal askPx;   // 卖一价（Ask Price）
    private BigDecimal askSz;   // 卖一价对应的数量（Ask Size）
    private BigDecimal bidPx;   // 买一价（Bid Price）
    private BigDecimal bidSz;   // 买一价对应的数量（Bid Size）
    private BigDecimal open24h; // 24小时开盘价
    private BigDecimal high24h; // 24小时最高价
    private BigDecimal low24h;  // 24小时最低价
    private BigDecimal volCcy24h; // 24小时成交量，以币为单位
    private BigDecimal vol24h;  // 24小时成交量，以张为单位
    private BigDecimal sodUtc0; // UTC+0 时开盘价
    private BigDecimal sodUtc8; // UTC+8 时开盘价
    private String ts;          // ticker数据产生时间戳，单位：毫秒
    private Date updateTime;    // 数据更新时间，用于页面显示
    
    /**
     * 构造函数，初始化更新时间为当前时间
     */
    public TickerInfo() {
        this.updateTime = new Date();
    }
    
    /**
     * 从API返回的JSON对象创建行情信息实例
     * 
     * @param jsonObject API返回的JSON对象
     * @return 行情信息实例
     */
    public static TickerInfo fromJsonObject(JSONObject jsonObject) {
        if (jsonObject == null) {
            return null;
        }
        
        TickerInfo ticker = new TickerInfo();
        ticker.setInstType(jsonObject.getString("instType"));
        ticker.setInstId(jsonObject.getString("instId"));
        ticker.setLast(safeParseDecimal(jsonObject.getString("last")));
        ticker.setLastSz(safeParseDecimal(jsonObject.getString("lastSz")));
        ticker.setAskPx(safeParseDecimal(jsonObject.getString("askPx")));
        ticker.setAskSz(safeParseDecimal(jsonObject.getString("askSz")));
        ticker.setBidPx(safeParseDecimal(jsonObject.getString("bidPx")));
        ticker.setBidSz(safeParseDecimal(jsonObject.getString("bidSz")));
        ticker.setOpen24h(safeParseDecimal(jsonObject.getString("open24h")));
        ticker.setHigh24h(safeParseDecimal(jsonObject.getString("high24h")));
        ticker.setLow24h(safeParseDecimal(jsonObject.getString("low24h")));
        ticker.setVolCcy24h(safeParseDecimal(jsonObject.getString("volCcy24h")));
        ticker.setVol24h(safeParseDecimal(jsonObject.getString("vol24h")));
        ticker.setSodUtc0(safeParseDecimal(jsonObject.getString("sodUtc0")));
        ticker.setSodUtc8(safeParseDecimal(jsonObject.getString("sodUtc8")));
        ticker.setTs(jsonObject.getString("ts"));
        return ticker;
    }
    
    /**
     * 安全解析字符串为BigDecimal，避免空值和格式错误导致的异常
     * 
     * @param value 要解析的数字字符串
     * @return 解析结果，如果解析失败则返回0
     */
    private static BigDecimal safeParseDecimal(String value) {
        try {
            return value != null ? new BigDecimal(value) : BigDecimal.ZERO;
        } catch (Exception e) {
            return BigDecimal.ZERO;
        }
    }
    
    /**
     * 计算24小时价格变化值
     * 
     * @return 最新价与24小时前开盘价的差值
     */
    public BigDecimal getPriceChange24h() {
        if (last == null || open24h == null || open24h.compareTo(BigDecimal.ZERO) == 0) {
            return BigDecimal.ZERO;
        }
        return last.subtract(open24h);
    }
    
    /**
     * 计算24小时价格变化百分比
     * 
     * @return 24小时价格变化百分比，如果开盘价为0则返回0
     */
    public BigDecimal getPriceChangePercent24h() {
        if (last == null || open24h == null || open24h.compareTo(BigDecimal.ZERO) == 0) {
            return BigDecimal.ZERO;
        }
        return last.subtract(open24h)
                .multiply(new BigDecimal("100"))
                .divide(open24h, 4, RoundingMode.HALF_UP);
    }
    
    /**
     * 获取格式化的24小时价格变化百分比，带%符号
     * 
     * @return 格式化的百分比字符串，如"+5.25%"或"-2.30%"
     */
    public String getFormattedPriceChangePercent24h() {
        BigDecimal percent = getPriceChangePercent24h();
        if (percent.compareTo(BigDecimal.ZERO) == 0) {
            return "0.00%";
        }
        
        String prefix = percent.compareTo(BigDecimal.ZERO) > 0 ? "+" : "";
        return prefix + percent.setScale(2, RoundingMode.HALF_UP).toPlainString() + "%";
    }
    
    /**
     * 获取格式化的最新成交价，保留特定小数位
     * 
     * @param scale 保留的小数位数
     * @return 格式化后的价格
     */
    public String getFormattedLastPrice(int scale) {
        if (last == null) {
            return "0";
        }
        return last.setScale(scale, RoundingMode.HALF_UP).toPlainString();
    }
    
    /**
     * 获取格式化的买一价，保留特定小数位
     * 
     * @param scale 保留的小数位数
     * @return 格式化后的价格
     */
    public String getFormattedBidPrice(int scale) {
        if (bidPx == null) {
            return "0";
        }
        return bidPx.setScale(scale, RoundingMode.HALF_UP).toPlainString();
    }
    
    /**
     * 获取格式化的卖一价，保留特定小数位
     * 
     * @param scale 保留的小数位数
     * @return 格式化后的价格
     */
    public String getFormattedAskPrice(int scale) {
        if (askPx == null) {
            return "0";
        }
        return askPx.setScale(scale, RoundingMode.HALF_UP).toPlainString();
    }
    
    /**
     * 获取买卖差价（Spread）
     * 
     * @return 卖一价与买一价之间的差值
     */
    public BigDecimal getSpread() {
        if (askPx == null || bidPx == null) {
            return BigDecimal.ZERO;
        }
        return askPx.subtract(bidPx);
    }
    
    /**
     * 获取买卖差价的百分比
     * 
     * @return 差价占买一价的百分比
     */
    public BigDecimal getSpreadPercent() {
        if (askPx == null || bidPx == null || bidPx.compareTo(BigDecimal.ZERO) == 0) {
            return BigDecimal.ZERO;
        }
        return getSpread()
                .multiply(new BigDecimal("100"))
                .divide(bidPx, 4, RoundingMode.HALF_UP);
    }
    
    /**
     * 获取格式化的行情数据时间
     * 
     * @return 格式化的时间字符串，如"2023-05-25 14:32:45"
     */
    public String getFormattedTimestamp() {
        if (ts == null || ts.isEmpty()) {
            return "";
        }
        
        try {
            long timestamp = Long.parseLong(ts);
            Date date = new Date(timestamp);
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            return sdf.format(date);
        } catch (Exception e) {
            return "";
        }
    }
    
    /**
     * 判断24小时价格是否上涨
     *
     * @return 如果当前价格高于24小时前返回true，否则返回false
     */
    public boolean isPriceUp() {
        if (last == null || open24h == null) {
            return false;
        }
        return last.compareTo(open24h) > 0;
    }
    
    /**
     * 检查是否为现货（Spot）产品
     *
     * @return 如果产品类型为SPOT返回true，否则返回false
     */
    public boolean isSpot() {
        return "SPOT".equalsIgnoreCase(instType);
    }
    
    /**
     * 检查是否为永续合约（Swap）产品
     *
     * @return 如果产品类型为SWAP返回true，否则返回false
     */
    public boolean isSwap() {
        return "SWAP".equalsIgnoreCase(instType);
    }
} 